
package com.bh.framework.network;

import java.io.EOFException;
import java.io.IOException;
import java.net.BindException;
import java.net.ConnectException;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeoutException;

import org.apache.http.HttpException;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.conn.ConnectionPoolTimeoutException;
import org.apache.http.message.BasicNameValuePair;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.os.Handler;
import android.os.Message;

import com.bh.framework.common.Constant;
import com.bh.framework.utils.JSONUtils;
import com.bh.framework.utils.Log;

/**
 * 异步网络请求
 * 
 * @author
 * 
 * @param <T>
 */
public class NetUpdatesTask<T> extends NetAsyncTask<Boolean, Integer, Object>
{
	private Context activity;
	private String url;
	private List<NameValuePair> paramList;
	private boolean isList = false;
	private Class<T> cls;
	private Handler handler;
	private int postType = Constant.GET;
	private boolean isAutoParserJson = true;
	private int flag;
	private boolean isShow = true;

	/**
	 * 构造方法，显示加载loading，并且返回数据是一个对象
	 * 
	 * @param activity
	 * @param url
	 *            请求路径
	 */
	public NetUpdatesTask(Context activity, String url)
	{
		super(activity, null, true, true, true);
		this.activity = activity;
		this.url = url;
	}

	/**
	 * 构造方法，显示加载loading，并且返回数据是一个对象
	 * 
	 * @param activity
	 * @param url
	 *            请求路径
	 * @param postType
	 *            网络的请求方式
	 */
	public NetUpdatesTask(Context activity, String url, int postType)
	{
		super(activity, null, true, true, true);
		this.activity = activity;
		this.url = url;
		this.postType = postType;
	}

	/**
	 * 构造方法，可设置loading是否显示
	 * 
	 * @param activity
	 * @param url
	 *            请求路径
	 * @param isShow
	 *            是否显示Loading
	 */
	public NetUpdatesTask(Context activity, String url, boolean isShow)
	{
		super(activity, null, true, true, isShow);
		this.activity = activity;
		this.url = url;
	}

	/**
	 * 构造方法，可设置loading是否显示
	 * 
	 * @param activity
	 * @param url
	 *            请求路径
	 * @param postType
	 *            设置发送请求的方式
	 * @param isShow
	 *            是否显示Loading
	 */
	public NetUpdatesTask(Context activity, String url, int postType,
			boolean isShow)
	{
		super(activity, null, true, true, isShow);
		this.activity = activity;
		this.url = url;
		this.postType = postType;
	}

	/**
	 * 构造方法，可设置loading是否显示和返回数据类型
	 * 
	 * @param activity
	 * @param url
	 *            请求路径
	 * @param isList
	 *            数据是否为List，true为list，false为单个对象
	 * @param isShow
	 *            是否显示Loading
	 */
	public NetUpdatesTask(Context activity, String url, boolean isList,
			boolean isShow)
	{
		super(activity, null, true, true, isShow);
		this.activity = activity;
		this.url = url;
		this.isList = isList;
	}

	/**
	 * 构造方法，可设置loading是否显示和返回数据类型
	 * 
	 * @param activity
	 * @param url
	 *            请求路径
	 * @param isList
	 *            数据是否为List，true为list，false为单个对象
	 * @param postType
	 *            设置发送请求的方式
	 * @param isShow
	 *            是否显示Loading
	 */
	public NetUpdatesTask(Context activity, String url, boolean isList,
			int postType, boolean isShow)
	{
		super(activity, null, true, true, isShow);
		this.activity = activity;
		this.url = url;
		this.isList = isList;
		this.postType = postType;
	}

	/**
	 * 设置网络获取数据的回调处理
	 * 
	 * @param handler
	 */
	public void setHandler(Handler handler)
	{
		this.handler = handler;
	}

	/**
	 * 设置是否自动解析json数据，true为自动解析，false为不解析，默认为true
	 * @param isAutoParserJson
	 */
	public void setAutoParserJson(boolean isAutoParserJson){
		this.isAutoParserJson = isAutoParserJson;
	}
	/**
	 * 返回数据为单个对象时，设置返回对象的类型
	 * 
	 * @param cls
	 */
	public void setClazz(Class<T> cls)
	{
		this.cls = cls;
	}

	/**
	 * 设置发送请求的方式
	 * 
	 * @param postType
	 */
	public void setPostType(int postType)
	{
		this.postType = postType;
	}

	/**
	 * 设置post请求时要传递的参数
	 * 
	 * @param params
	 */
	public void setParams(Map<String, String> params)
	{

		if (params != null && params.size() > 0)
		{
			paramList = new ArrayList<NameValuePair>();
			Set<String> keySet = params.keySet();
			for (String key : keySet)
			{
				NameValuePair nameValue = new BasicNameValuePair(key,
						params.get(key));
				paramList.add(nameValue);
				Log.i("TEAG==url", url + "?" + key + "=" + params.get(key));
			}
		}
	}

	@Override
	protected Object doInBackground(Boolean... params)
	{
		Object info = null;
		NetRequest netReq = NetRequest.getInstance(activity);
		Log.d(netReq.isWifiEnabled() + "============="
				+ netReq.isNetworkConnected());
		if (netReq.isWifiEnabled() || netReq.isNetworkConnected())
		{
			try
			{
				String result;
				if (postType == Constant.GET)
				{
					result = netReq.getRequest4Str(url);
				} else
				{
					result = netReq.postRequest(paramList, url);
				}
				if(isAutoParserJson){
					if (isList)
					{
						List<T> obj = JSONUtils.fromJson(result);
						info = obj;
					} else
					{
						T obj = JSONUtils.fromJson(result, cls);
						info = obj;
					}
				}else{
					info = result;
				}
			} catch (Exception e)
			{
				e.printStackTrace();
				if (e instanceof TimeoutException
						|| e instanceof SocketTimeoutException
						|| e instanceof ConnectionPoolTimeoutException)
				{
					// 抛出此类异常，表示连接超时
					info = Constant.TIMEOUT_EXCEPTION_CODE;
				} else if (e instanceof SocketException)
				{
					// 抛出此类异常，表示连接已关闭
					info = Constant.SOCKET_EXCEPTION_CODE;
				} else if (e instanceof EOFException)
				{
					// 抛出此类异常，表示连接丢失
					info = Constant.EOF_EXCEPTION_CODE;
				} else if (e instanceof ConnectException)
				{
					// 抛出此类异常，表示无法连接
					info = Constant.CONNECT_EXCEPTION_CODE;
				} else if (e instanceof BindException)
				{
					// 抛出此类异常，表示端口已经被占用
					info = Constant.BIND_EXCEPTION_CODE;
				} else if (e instanceof HttpException)
				{
					// 数据响应异常
					info = Constant.HTTP_EXCEPTION_CODE;
				} else if (e instanceof IOException)
				{
					// 输入输出流异常
					info = Constant.IO_EXCEPTION_CODE;
				} else if (e instanceof UnknownHostException)
				{
					// 请求路径异常
					info = Constant.UNKNOWNHOST_EXCEPTION_CODE;
				} else if (e instanceof ParseException)
				{
					// 数据格式异常
					info = Constant.PARSE_EXCEPTION_CODE;
				} else
				{
					// 其他未知异常
					info = Constant.UNKNOWN_EXCEPTION_CODE;
				}
			}
		} else
		{
			info = Constant.NET_ENABLED_CODE;
		}
		return info;
	}
	/**
	 * 
	 * @param flag
	 */
	public void setFlag(int flag)
	{
		this.flag = flag;
	}
	@Override
	protected void onPostExecute(Object result)
	{
		super.onPostExecute(result);
		if (handler != null)
		{
			Message message;
			if(result instanceof Integer){
				if(isShow){
					new AlertDialog.Builder(activity).setPositiveButton("确定", new OnClickListener()
					{
						
						@Override
						public void onClick(DialogInterface dialog, int which)
						{
							// TODO Auto-generated method stub
							dialog.cancel();
						}
					}).setMessage("对不起，您的网络无法访问").create().show();
				}
				message = Message.obtain(
						handler, Constant.DID_ERROR, result);
				message.arg1 = flag;
			}else{
				message = Message.obtain(
						handler, Constant.DID_SUCCEED, result);
				message.arg1 = flag;
			}
			handler.sendMessage(message);
		}
	}
	
	public void isShowExcepDialog(boolean isShow){
		this.isShow = isShow;
	}
}
